package com.arofoxmsn.repository;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;

public class BaseTable<T> {
	
	public static SessionFactory sessionIntance = null;
	
	private Class myClass;
	
	public BaseTable(Class aClass){
		this.myClass = aClass;
	}
	
	protected static SessionFactory getInstance(){
		if(sessionIntance == null){
			MyHibernateConfig.init();
			sessionIntance = new Configuration().configure().buildSessionFactory();
		}
		return sessionIntance;
	}
	
	protected Session getOpenSession(){
		SessionFactory factory = BaseTable.getInstance();
		Session session = factory.openSession();
		session.beginTransaction();
		return session;
	}
	
	protected static void destroyInstance(){
		sessionIntance = null;
	}
	
	protected List<T> retrieveAll(Criterion... criterios){	
		Session session = getOpenSession();
		Criteria criteria = session.createCriteria(this.myClass);
		for(Criterion oneCriterio : criterios){
			criteria.add(oneCriterio);
		}
		List<T> listToReturn = (List<T>) criteria.list();
		session.getTransaction().commit();
		session.close();
		return listToReturn;
	}
	
	public T retrieveById(int id){
		return retrieveAll(Restrictions.eq("id", id)).get(0);
	}
	
	public List<T> retrieveByIds(int ...ids){
		return retrieveAll(Restrictions.in("id", Arrays.asList(ids)));
	}
	
	/**
	 * this method is responsible for saving object data
	 * @param objects
	 */
	public void save(Object...objects){
		Session session = getOpenSession();
		for(Object oneOfAll : objects)
			session.saveOrUpdate(oneOfAll);
		session.getTransaction().commit();
		session.close();
	}
	
	//template
//	protected abstract Class getInheritanceClass();

}
